package cn.edu.yzu.scholarship.biz;

import static net.sf.dynamicreports.report.builder.DynamicReports.cmp;
import static net.sf.dynamicreports.report.builder.DynamicReports.col;
import static net.sf.dynamicreports.report.builder.DynamicReports.report;
import static net.sf.dynamicreports.report.builder.DynamicReports.stl;
import static net.sf.dynamicreports.report.builder.DynamicReports.type;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.dynamicreports.jasper.builder.JasperReportBuilder;
import net.sf.dynamicreports.report.builder.column.ColumnBuilder;
import net.sf.dynamicreports.report.builder.component.ComponentBuilder;
import net.sf.dynamicreports.report.builder.style.StyleBuilder;
import net.sf.dynamicreports.report.constant.HorizontalAlignment;
import net.sf.dynamicreports.report.constant.VerticalAlignment;
import net.sf.dynamicreports.report.datasource.DRDataSource;
import net.sf.dynamicreports.report.definition.datatype.DRIDataType;
import net.sf.jasperreports.engine.JRDataSource;
import cn.edu.yzu.scholarship.kit.ExcelKit;
import cn.edu.yzu.scholarship.kit.Sak;

public class ReportBiz {

	private final static Map<String,ColumnBuilder<?,?>> columnMap = new HashMap<String,ColumnBuilder<?,?>>();
	private final static Map<String,String> headerMap = new HashMap<String,String>();
	
	private static StyleBuilder baseStyle = stl.style().setBorder(stl.penThin());
	private static StyleBuilder centerStyle = stl.style(baseStyle).setHorizontalAlignment(HorizontalAlignment.CENTER)
		.setVerticalAlignment(VerticalAlignment.MIDDLE).bold();
	private static final int DEFAULT_PREVIEW_SIZE = 20;
	
	static {
		putColumnAndHeaderMap("xh","学号",type.stringType());
		putColumnAndHeaderMap("xm","姓名",type.stringType());
		putColumnAndHeaderMap("xb","性别",type.stringType());
		putColumnAndHeaderMap("scholarshipName","奖学金",type.stringType());
		putColumnAndHeaderMap("money","奖金",type.stringType());
		putColumnAndHeaderMap("scholarshipMoney","奖金",type.stringType());
		putColumnAndHeaderMap("lqyxsmc","学院名称",type.stringType());
		putColumnAndHeaderMap("cwbh","财务编号",type.stringType());
		putColumnAndHeaderMap("lqzymc","专业",type.stringType());
		putColumnAndHeaderMap("lqlbm","录取类别码",type.stringType());
		putColumnAndHeaderMap("lqlbmc","录取类别",type.stringType());
		putColumnAndHeaderMap("levelName","获奖等级",type.stringType());
		putColumnAndHeaderMap("memo","备注",type.stringType());
	}
	
	/**
	 * 使用POI实现导出
	 * @param title
	 * @param columns
	 * @param data
	 * @return
	 */
	public static void exportExcel(String absPath,String title,String[] columns, List<Map<String,Object>> data) {
		exportExcel(absPath, title, columns, data, null);
	}
	
	public static void exportExcel(String absPath,String title,String[] columns, List<Map<String,Object>> data, List<String> footer) {
		String[] headers = new String[columns.length];
		for(int i = 0; i < columns.length; i++) {
			headers[i] = headerMap.get(columns[i]);
		}
		
		try {
			File file = new File(absPath);
			Sak.createParentDirs(file);
			FileOutputStream fos = new FileOutputStream(file);
			ExcelKit.exportExcel(title, title, columns, headers, data, footer, fos);
			
			fos.close();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 使用dynamic reports 实现报表导出
	 * @param title
	 * @param columns
	 * @param data
	 * @return
	 */
	public static JasperReportBuilder fillJasperReport(String title,String[] columns, List<Map<String,Object>> data) {
		
		JasperReportBuilder builder = 
			initReport()
			.columns(buildColumns(columns))
			.title(buildTitle(title))
			.setDataSource(buildDS(columns,data));
		
		return builder;
	}
	
	/**
	 * 使用dynamic reports实现预览
	 * @param title
	 * @param columns
	 * @param data
	 * @return
	 */
	public static JasperReportBuilder previewJasperReport(String title,String[] columns, List<Map<String,Object>> data) {
		data = buildPreviewData(columns, data);
		
		JasperReportBuilder builder = 
				initReport()
				.columns(buildColumns(columns))
				.title(buildTitle(title))
				.setDataSource(buildDS(columns,data));
		
		return builder;
	}

	private static List<Map<String, Object>> buildPreviewData(String[] columns,
			List<Map<String, Object>> data) {
		if(data.size() > DEFAULT_PREVIEW_SIZE) {//只显示前后20条记录
			List<Map<String,Object>> _data = new ArrayList<Map<String,Object>>(data.subList(0, DEFAULT_PREVIEW_SIZE/2));
			Map<String,Object> row = new HashMap<String,Object>();
			for(int i = 0; i < columns.length; i++) {
				row.put(columns[i], "......");
			}
			_data.add(row);
			_data.addAll(data.subList(data.size() - DEFAULT_PREVIEW_SIZE/2, data.size()));
			
			data = _data;
		}
		return data;
	}
	
	private static JRDataSource buildDS(String[] columns, List<Map<String, Object>> data) {
		DRDataSource ds = new DRDataSource(columns);
		
		for(Map<String,Object> map : data) {
			Object[] rows = new Object[columns.length];
			for(int i = 0; i < columns.length; i++) {
				rows[i] = map.get(columns[i]);
			}
			ds.add(rows);
		}
		
		return ds;
	}

	private static ComponentBuilder<?, ?> buildTitle(String title) {
		return cmp.text(title).setStyle(centerStyle);
	}

	private static ColumnBuilder<?, ?>[] buildColumns(String[] columns) {
		if(columns == null) throw new RuntimeException("columns cannot be empty!");
		
		ColumnBuilder<?,?>[] builders = new ColumnBuilder<?,?>[columns.length];
		for(int i = 0; i < columns.length; i++) {
			builders[i] = columnMap.get(columns[i]);
		}
		
		return builders;
	}

	private static JasperReportBuilder initReport() {
		return report()
			.setColumnTitleStyle(centerStyle)
			.setColumnStyle(baseStyle);
	}
	
	
	private static <T> void putColumnAndHeaderMap(String key,String text, DRIDataType<? super T, T> type) {
		columnMap.put(key, col.column(text,key,type));
		headerMap.put(key, text);
	}
}
